<template>
  <div>
    <el-card style="margin-bottom:20px">
      <CategorySelect @changeCategoryId="changeCategoryId"  ref="cs"/>
    </el-card>
    <el-card>
      <!--平台属性及列表数据界面-->
      <div v-show="!isShowAddOrUpdateAttr">
        <!--按钮-->
        <el-button type="primary" icon="el-icon-plus" @click="showAddAttr" :disabled="!category3Id">添加属性</el-button>
        <!--表格-->
        <el-table :data="attrList" border stripe style="width: 100%" v-loading="loading">
          <el-table-column type="index" label="序号" width="80" align="center">
          </el-table-column>
          <el-table-column label="属性名称" width="150">
            <template slot-scope="{row}">
              <el-badge :value="row.attrValueList.length" class="item">
                <el-button size="small">{{row.attrName}}</el-button>
              </el-badge>
            </template>
          </el-table-column>
          <el-table-column label="属性值列表">
            <template slot-scope="{row}">
              <!--遍历平台属性对象中的attrValueList数组-->
              <el-tag type="success" v-for="(val,index) in row.attrValueList" :key="val.id">{{val.valueName}}</el-tag>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="150">
            <template slot-scope="{row}">
              <HintButton title="修改属性" size="mini" type="primary" icon="el-icon-edit" @click="showUpdateAttr(row)" />
                <el-popconfirm :title="`您确定要删除${row.attrName}吗？`" @onConfirm="deleteAttr(row.id)">
                  <HintButton slot="reference" title="删除属性" size="mini" type="danger" icon="el-icon-delete" />
                </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <!--添加/修改平台属性及值界面-->
      <div v-show="isShowAddOrUpdateAttr">
        <el-form inline :model="formData">
          <!--属性名称-->
          <el-form-item label="属性名称">
            <el-input type="text" v-model="formData.attrName" placeholder="请输入属性名称"></el-input>
          </el-form-item>
          <!--两个按钮-->
          <div style="margin-bottom:20px">
            <!-- disable动态数据  里面判断是不是输入属性名  空得话就是置灰 不空就打开模式 -->
            <el-button type="primary" icon="el-icon-plus" @click="addAttrValue" :disabled="!formData.attrName.trim().length">添加属性值</el-button>
            <el-button @click="isShowAddOrUpdateAttr=false">取消</el-button>
          </div>
          <!--表格-->
          <el-table :data="formData.attrValueList" border stripe style="width: 100%">
            <el-table-column type="index" label="序号" width="80" align="center">
            </el-table-column>
            <el-table-column label="属性值名称">
              <template slot-scope="{row,$index}">
                <!-- 通过每一行的对象的edit属性作为标识,如果是false 则显示span的里面内容 -->
                <el-input type="text" v-if="row.edit" v-model="row.valueName" placeholder="请输入属性值" size="mini"
                  :ref="$index" @blur="toView(row)" @keyup.native.enter="toView(row)"></el-input>
                <span type="success" v-else @click="toEdit(row,$index)" style="width:100%;display:inline-block">{{row.valueName}}</span>
              </template>
            </el-table-column>
            <el-table-column label="操作">
              <template slot-scope="{row,$index}">
                <!--这里注意有一个坑 就是气泡框的事件中 要一定加 'on' 文档中没有体现 -->
                <el-popconfirm :title="`您确定要删除${row.attrName}吗？`" @onConfirm="deleteValue($index)">
                  <HintButton slot="reference" size="mini" type="danger" icon="el-icon-delete" title="删除属性值" />
                </el-popconfirm>
              </template>
            </el-table-column>
          </el-table>
          <!--两个按钮-->
          <div style="margin-top:20px">
            <el-button type="primary" @click="save">保存</el-button>
            <el-button @click="isShowAddOrUpdateAttr=false">取消</el-button>
          </div>
        </el-form>
      </div>
    </el-card>
  </div>
</template>

<script>
  // 引入深拷贝插件lodash
  import cloneDeep from 'lodash/cloneDeep'
  export default {
    name: 'Attr',
    data() {
      return {
        // 收集数据
        category1Id: '', // 一级分类的id
        category2Id: '', // 二级分类的id
        category3Id: '', // 三级分类的id
        attrList: [], // 平台属性数组数据
        isShowAddOrUpdateAttr: false, // 添加或者修改平台属性值的画面的标识
        loading: false, // 加载数据效果的标识
        // 用来存储平台属性对象的
        formData: {
          attrName: '', // 平台属性名字
          attrValueList: [] // 平台属性值对象数组
        }
      }
    },
    // 监视属性
    watch:{
      // 对 添加 或者修改平台属性界面的标识 进行监视
      isShowAddOrUpdateAttr(val){
        this.$refs.cs.isDisabled = val
      }
    },
    methods: {
      // 获取平台属性的数据
      async getAttrList() {
        const result = await this.$API.attr.getAttrInfoList(
          this.category1Id,
          this.category2Id,
          this.category3Id
        )
        this.loading = false // 关闭加载效果
        if (result.code === 200) {
          // 更新数据
          this.attrList = result.data
        }
      },
      // 选中的分类内容改变的时候所分发的自定义事件对应的回调函数
      changeCategoryId({
        level,
        categoryId
      }) {
        // 一级分类的id/二级分类的id/三级分类的id
        // 保存起来,需要在三级分类的id传过来之后调用接口
        if (level === 1) {
          this.category1Id = categoryId
          // 重置二级/三级分类的id和平台属性数组
          this.category2Id = null
          this.category3Id = null
          this.attrList = []
        } else if (level === 2) {
          this.category2Id = categoryId
          // 重置三级分类的id和平台属性数组
          this.category3Id = null
          this.attrList = []
        } else {
          this.category3Id = categoryId
          this.loading = true // 获取平台属性值前设置加载的效果
          // 三级分类的时候调用接口
          this.getAttrList()
        }
      },
      // 点击添加属性按钮, 显示 添加平台属性界面
      showAddAttr() {
        this.formData={
          attrName:'' ,// 属性名字
          attrValueList:[], //属性值对象数组
          categoryId:this.category3Id,// 三级分类的id
          categoryLevel:3 //级别3级
        }
        this.isShowAddOrUpdateAttr = true
      },
      // 点击修改属性按钮, 显示 修改平台属性界面
      showUpdateAttr(attrInfo) {
        // 更新传入过来的数据,
        // this.formData = attrInfo
        // 浅拷贝--在这里不能用 是改变属性时原对象不变
        // 这里使用深拷贝
        this.formData = cloneDeep(attrInfo)
        // 显示界面
        this.isShowAddOrUpdateAttr = true
      },
      // 点击添加属性值按钮的事件的回调函数
      addAttrValue() {
        // formData.attrValueList
        // 数组中有三个数据,那么表格就有三行,添加一行,无非就是为数组添加一个数据
        // 此时数组中的每个数据是一个对象,那么就是在数组中添加一个对象即可
        this.formData.attrValueList.push({
          attrId: this.formData.id, // 存储的是当前平台属性值对象所在的平台属性对象的id
          valueName: '',
          edit: true // 控制编辑和查看的标识
        })
        // 设置当前的新的一行中的文本框有焦点--默认的光标
        // 新添加的属性值的这一行中的文本框的索引----就是最后一行的索引
        this.$nextTick(() => {
          this.$refs[this.formData.attrValueList.length - 1].focus()
        })
      },
      // 查看模式
      toView(attrValue) {
        // 判断文本框中是否有数据
        // 如果没有数据,则不会变成查看模式
        if (attrValue.valueName.trim() === '') return
        // 这时已经有了数据,但是新录入的数据和之前已经存在的数据不能一样
        const isRepeat = this.formData.attrValueList.filter(
          val => val.valueName === attrValue.valueName).length === 2
        if (isRepeat) {
          // 这时新录入的数据和数组中已经存在的数据是一样的,这是不允许的
          this.$message.warning('您输入了重复的数据,请重新输入')
          attrValue.valueName = '' // 直接清空重复的数据
          return
        }
        // 这时说明数据存在,可以变成查看模式
        attrValue.edit = false
      },
      // 编辑模式
      toEdit(attrValue,index) {
          // 判断当前这一行的对象标识是否存在
          // 如果不存在,那么就说明此时属性值对象中没有edit  
          // 需要添加edit属性
          // 使用的是一个hasOwnProperty方法--这个方法返回值是一个布尔值
          // 在这里是用来判断attrValue中有没有edit这个属性 
          if(!attrValue.hasOwnProperty('edit')){
            // 添加的这个属性需要是响应式的
            // 使用的Vue中$set方法  它是Vue.set的一个实例对象中的属性
            this.$set(attrValue,'edit',true)
          }else{
            // 在这说明这个属性是后添加的
            attrValue.edit = true
          }
          // 如果变成了编辑模式  此时这一行除了文本框了
          // 需要设置文本框有焦点  --- 为了用户体验更好
          this.$nextTick(()=>{
            this.$refs[index].focus()
          })
      },
      // 删除平台属性值的操作
      deleteValue(index){
        alert(111)
        // 将平台属性对象中的属性值数组删除对应的索引
        // 使用的是数组中的splice方法
        // splice 第一个参数 删除谁  第二个参数  删除几个
          this.formData.attrValueList.splice(index,1)
          // 提示消息
          this.$message.success('删除成功')
      },
      // 保存回调
      async save(){
          // 如果属性名字不存在 就不做修改
          if(this.formData.attrName.trim().length === 0) return
          // 针对属性值对象数组中的数据进行过滤操作
          this.formData.attrValueList = this.formData.attrValueList.filter((attrValue)=>{
            //移除编辑或者查看模式的标识属性
            // 这里使用的是一个delete关键字
            // 可以删除属性值  
            delete attrValue.edit // 删除自定义的标识属性
            // 如果属性值是空的  那么直接返回
            // 这里需要注意  用到了'!!'这个是直接返回布尔  就是取反在取反
            return !!attrValue.valueName.trim() // 直接返回布尔值
            // return attrValue.valueName.trim() //这个是返回字符串 还要在隐士转换布尔--复杂
          })
          // 再次筛选一下
          if(this.formData.attrValueList.length === 0) {
            // 提示消息
            this.$message.warning('至少添加一个平台属性值名称')
            return
          }
          // 都判断完之后  那么就是属性值存在了
          // 调用接口
          const result = await this.$API.attr.addOrUpdateAttrInfo(this.formData)
          // console.log(result.data)
          if(result.code !== 200){
            // 提示消息
            this.$message.error('操作失败')
            return
          }
          // 到这里 说明调用接口成功
          // 提示
          this.$message.success('操作成功')
          // 关闭当前页面
          this.isShowAddOrUpdateAttr = false
          // 刷新页面
          this.getAttrList()
      },
      // 删除平台属性
      async deleteAttr(attrId){
          const result = await this.$API.attr.deleteAttrInfoById(attrId)
          if(result.code !== 200){
            // 提示信息
            this.$message.error('删除失败')
            return
          }       
          // 提示
          this.$message.success('删除成功')
          // 刷新页面
          this.getAttrList()
      }
    }
  }

</script>

<style>
  .item {
    margin-top: 10px;
    margin-right: 40px;
  }

</style>
